package com.hsyt.pms.security.rsa.util;


import org.apache.commons.codec.binary.Base64;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.apache.commons.codec.binary.Base64;

public class RSAEncrypt {
	public static final String KEY_ALGORITHM = "RSA";
	public static final String CIPHER_ALGORITHM_ECB1 = "RSA/ECB/PKCS1Padding";
	private static final char[] HEX_CHAR = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

	public RSAEncrypt() {
	}

	public static RsaKeyPair genKeyPair() {
		KeyPairGenerator keyPairGen = null;

		try {
			keyPairGen = KeyPairGenerator.getInstance("RSA");
		} catch (NoSuchAlgorithmException var6) {
			var6.printStackTrace();
		}

		keyPairGen.initialize(1024, new SecureRandom());
		KeyPair keyPair = keyPairGen.generateKeyPair();
		RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();
		RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();
		String publicKeyString = Base64.encodeBase64String(publicKey.getEncoded());
		String privateKeyString = Base64.encodeBase64String(privateKey.getEncoded());
		return new RsaKeyPair(privateKeyString, publicKeyString);
	}

	public static void genKeyPair(String filePath) {
		KeyPairGenerator keyPairGen = null;

		try {
			keyPairGen = KeyPairGenerator.getInstance("RSA");
		} catch (NoSuchAlgorithmException var12) {
			var12.printStackTrace();
		}

		keyPairGen.initialize(1024, new SecureRandom());
		KeyPair keyPair = keyPairGen.generateKeyPair();
		RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();
		RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();

		try {
			String publicKeyString = Base64.encodeBase64String(publicKey.getEncoded());
			String privateKeyString = Base64.encodeBase64String(privateKey.getEncoded());
			FileWriter pubfw = new FileWriter(filePath + "/publicKey.keystore");
			FileWriter prifw = new FileWriter(filePath + "/privateKey.keystore");
			BufferedWriter pubbw = new BufferedWriter(pubfw);
			BufferedWriter pribw = new BufferedWriter(prifw);
			pubbw.write(publicKeyString);
			pribw.write(privateKeyString);
			pubbw.flush();
			pubbw.close();
			pubfw.close();
			pribw.flush();
			pribw.close();
			prifw.close();
		} catch (Exception var11) {
			var11.printStackTrace();
		}

	}

	public static String loadPublicKeyByFile(String path) throws AmpSecurityException {
		try {
			BufferedReader br = new BufferedReader(new FileReader(path + "/publicKey.keystore"));
			String readLine = null;
			StringBuilder sb = new StringBuilder();

			while((readLine = br.readLine()) != null) {
				sb.append(readLine);
			}

			br.close();
			return sb.toString();
		} catch (IOException var4) {
			throw new AmpSecurityException("公钥数据流读取错误", var4);
		} catch (NullPointerException var5) {
			throw new AmpSecurityException("公钥输入流为空", var5);
		}
	}

	public static RSAPublicKey loadPublicKeyByStr(String publicKeyStr) throws AmpSecurityException {
		try {
			byte[] buffer = Base64.decodeBase64(publicKeyStr);
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
			return (RSAPublicKey)keyFactory.generatePublic(keySpec);
		} catch (NoSuchAlgorithmException var4) {
			throw new AmpSecurityException("无此算法", var4);
		} catch (InvalidKeySpecException var5) {
			throw new AmpSecurityException("公钥非法", var5);
		} catch (NullPointerException var6) {
			throw new AmpSecurityException("公钥数据为空", var6);
		}
	}

	public static String loadPrivateKeyByFile(String path) throws AmpSecurityException {
		try {
			BufferedReader br = new BufferedReader(new FileReader(path + "/privateKey.keystore"));
			String readLine = null;
			StringBuilder sb = new StringBuilder();

			while((readLine = br.readLine()) != null) {
				sb.append(readLine);
			}

			br.close();
			return sb.toString();
		} catch (IOException var4) {
			throw new AmpSecurityException("私钥数据读取错误", var4);
		} catch (NullPointerException var5) {
			throw new AmpSecurityException("私钥输入流为空", var5);
		}
	}

	public static RSAPrivateKey loadPrivateKeyByStr(String privateKeyStr) throws AmpSecurityException {
		try {
			byte[] buffer = Base64.decodeBase64(privateKeyStr);
			PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			return (RSAPrivateKey)keyFactory.generatePrivate(keySpec);
		} catch (NoSuchAlgorithmException var4) {
			throw new AmpSecurityException("无此算法", var4);
		} catch (InvalidKeySpecException var5) {
			throw new AmpSecurityException("私钥非法", var5);
		} catch (NullPointerException var6) {
			throw new AmpSecurityException("私钥数据为空", var6);
		}
	}

	public static String encryptByPublicKeyStr(String publicKeyStr, String plainTextData) throws AmpSecurityException {
		return encrypt(loadPublicKeyByStr(publicKeyStr), plainTextData.getBytes(), false);
	}

	public static String encryptByPublicKeyStr(String publicKeyStr, String plainTextData, boolean isUrlSafe) throws AmpSecurityException {
		return encrypt(loadPublicKeyByStr(publicKeyStr), plainTextData.getBytes(), isUrlSafe);
	}

	public static String encrypt(RSAPublicKey publicKey, byte[] plainTextData, boolean isUrlSafe) throws AmpSecurityException {
		if (publicKey == null) {
			throw new AmpSecurityException("加密公钥为空, 请设置");
		} else {
			Cipher cipher = null;

			try {
				cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
				cipher.init(1, publicKey);
				byte[] output = cipher.doFinal(plainTextData);
				return isUrlSafe ? Base64.encodeBase64URLSafeString(output) : Base64.encodeBase64String(output);
			} catch (NoSuchAlgorithmException var5) {
				throw new AmpSecurityException("无此加密算法", var5);
			} catch (NoSuchPaddingException var6) {
				throw new AmpSecurityException("加密异常", var6);
			} catch (InvalidKeyException var7) {
				throw new AmpSecurityException("加密公钥非法,请检查", var7);
			} catch (IllegalBlockSizeException var8) {
				throw new AmpSecurityException("明文长度非法", var8);
			} catch (BadPaddingException var9) {
				throw new AmpSecurityException("明文数据已损坏", var9);
			}
		}
	}

	public static String encryptByPrivateKeyStr(String privateKeyStr, String plainTextData) throws AmpSecurityException {
		return encrypt(loadPrivateKeyByStr(privateKeyStr), plainTextData.getBytes(), false);
	}

	public static String encryptByPrivateKeyStr(String privateKeyStr, String plainTextData, boolean isUrlSafe) throws AmpSecurityException {
		return encrypt(loadPrivateKeyByStr(privateKeyStr), plainTextData.getBytes(), isUrlSafe);
	}

	public static String encrypt(RSAPrivateKey privateKey, byte[] plainTextData, boolean isUrlSafe) throws AmpSecurityException {
		if (privateKey == null) {
			throw new AmpSecurityException("加密私钥为空, 请设置");
		} else {
			Cipher cipher = null;

			try {
				cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
				cipher.init(1, privateKey);
				byte[] output = cipher.doFinal(plainTextData);
				return isUrlSafe ? Base64.encodeBase64URLSafeString(output) : Base64.encodeBase64String(output);
			} catch (NoSuchAlgorithmException var5) {
				throw new AmpSecurityException("无此加密算法", var5);
			} catch (NoSuchPaddingException var6) {
				throw new AmpSecurityException("加密异常", var6);
			} catch (InvalidKeyException var7) {
				throw new AmpSecurityException("加密私钥非法,请检查", var7);
			} catch (IllegalBlockSizeException var8) {
				throw new AmpSecurityException("明文长度非法", var8);
			} catch (BadPaddingException var9) {
				throw new AmpSecurityException("明文数据已损坏", var9);
			}
		}
	}

	public static String decryptByPrivateKeyStr(String privateKeyStr, String cipherData) throws AmpSecurityException {
		return decrypt(loadPrivateKeyByStr(privateKeyStr), Base64.decodeBase64(cipherData));
	}

	public static String decrypt(RSAPrivateKey privateKey, byte[] cipherData) throws AmpSecurityException {
		if (privateKey == null) {
			throw new AmpSecurityException("解密私钥为空, 请设置");
		} else {
			Cipher cipher = null;

			try {
				cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
				cipher.init(2, privateKey);
				byte[] output = cipher.doFinal(cipherData);
				return (new String(output)).trim();
			} catch (NoSuchAlgorithmException var4) {
				throw new AmpSecurityException("无此解密算法", var4);
			} catch (NoSuchPaddingException var5) {
				throw new AmpSecurityException("解密异常", var5);
			} catch (InvalidKeyException var6) {
				throw new AmpSecurityException("解密私钥非法,请检查", var6);
			} catch (IllegalBlockSizeException var7) {
				throw new AmpSecurityException("密文长度非法", var7);
			} catch (BadPaddingException var8) {
				throw new AmpSecurityException("密文数据已损坏", var8);
			}
		}
	}

	public static String decryptByPublicKeyStr(String publicKeyStr, String cipherData) throws AmpSecurityException {
		return decrypt(loadPublicKeyByStr(publicKeyStr), Base64.decodeBase64(cipherData));
	}

	public static String decrypt(RSAPublicKey publicKey, byte[] cipherData) throws AmpSecurityException {
		if (publicKey == null) {
			throw new AmpSecurityException("解密公钥为空, 请设置");
		} else {
			Cipher cipher = null;

			try {
				cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
				cipher.init(2, publicKey);
				byte[] output = cipher.doFinal(cipherData);
				return (new String(output)).trim();
			} catch (NoSuchAlgorithmException var4) {
				throw new AmpSecurityException("无此解密算法", var4);
			} catch (NoSuchPaddingException var5) {
				throw new AmpSecurityException("解密异常", var5);
			} catch (InvalidKeyException var6) {
				throw new AmpSecurityException("解密公钥非法,请检查", var6);
			} catch (IllegalBlockSizeException var7) {
				throw new AmpSecurityException("密文长度非法", var7);
			} catch (BadPaddingException var8) {
				throw new AmpSecurityException("密文数据已损坏", var8);
			}
		}
	}

	public static String byteArrayToString(byte[] data) {
		StringBuilder stringBuilder = new StringBuilder();

		for(int i = 0; i < data.length; ++i) {
			stringBuilder.append(HEX_CHAR[(data[i] & 240) >>> 4]);
			stringBuilder.append(HEX_CHAR[data[i] & 15]);
			if (i < data.length - 1) {
				stringBuilder.append(' ');
			}
		}

		return stringBuilder.toString();
	}
}
